using System;
using System.Net;
using System.Threading.Tasks;

namespace muduoDotNet.Tests.Common
{
    /// <summary>
    /// 测试工具类
    /// </summary>
    public static class TestUtils
    {
        /// <summary>
        /// 获取可用的端口号
        /// </summary>
        /// <returns>可用端口号</returns>
        public static int GetAvailablePort()
        {
            using var listener = new System.Net.Sockets.TcpListener(IPAddress.Loopback, 0);
            listener.Start();
            var port = ((IPEndPoint)listener.LocalEndpoint).Port;
            listener.Stop();
            return port;
        }

        /// <summary>
        /// 生成测试用的随机字符串
        /// </summary>
        /// <param name="length">长度</param>
        /// <returns>随机字符串</returns>
        public static string GenerateRandomString(int length = 10)
        {
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            var random = new Random();
            var result = new char[length];
            
            for (int i = 0; i < length; i++)
            {
                result[i] = chars[random.Next(chars.Length)];
            }
            
            return new string(result);
        }

        /// <summary>
        /// 生成测试用的随机字节数组
        /// </summary>
        /// <param name="size">大小</param>
        /// <returns>随机字节数组</returns>
        public static byte[] GenerateRandomBytes(int size)
        {
            var random = new Random();
            var bytes = new byte[size];
            random.NextBytes(bytes);
            return bytes;
        }

        /// <summary>
        /// 创建测试用的Buffer
        /// </summary>
        /// <param name="data">初始数据</param>
        /// <returns>Buffer实例</returns>
        public static Buffer CreateTestBuffer(string data = "")
        {
            var buffer = new Buffer();
            if (!string.IsNullOrEmpty(data))
            {
                buffer.Append(data);
            }
            return buffer;
        }

        /// <summary>
        /// 断言在指定时间内条件为真
        /// </summary>
        /// <param name="condition">条件函数</param>
        /// <param name="timeoutMs">超时时间（毫秒）</param>
        /// <param name="message">失败消息</param>
        public static async Task AssertEventuallyAsync(Func<bool> condition, int timeoutMs = 5000, string message = "Condition was not met within timeout")
        {
            var timeout = DateTime.UtcNow.AddMilliseconds(timeoutMs);
            
            while (DateTime.UtcNow < timeout)
            {
                if (condition())
                    return;
                    
                await Task.Delay(50);
            }
            
            throw new TimeoutException(message);
        }

        /// <summary>
        /// 安全运行异步任务，捕获异常
        /// </summary>
        /// <param name="task">任务</param>
        /// <param name="timeoutMs">超时时间（毫秒）</param>
        /// <returns>是否成功完成</returns>
        public static async Task<bool> SafeRunAsync(Func<Task> task, int timeoutMs = 5000)
        {
            try
            {
                await Task.WhenAny(task(), Task.Delay(timeoutMs));
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}